package com.dd.cloud.user.service.aicms.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.user.config.ZerkProperties;
import com.dd.cloud.user.entity.aicms.AicmsDisease;
import com.dd.cloud.user.mapper.aicms.AicmsDiseaseMapper;
import com.dd.cloud.user.req.aicms.DepAndFindDiseaseReq;
import com.dd.cloud.user.res.aicms.DepAndFindDiseaseRes;
import com.dd.cloud.user.res.aicms.SearchRes;
import com.dd.cloud.user.service.aicms.IAicmsDiseaseService;
import com.dd.cloud.user.vo.DiseaseVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author czg
 * @since 2022-04-27
 */
@Service
@Slf4j
public class AicmsDiseaseServiceImpl extends ServiceImpl<AicmsDiseaseMapper, AicmsDisease> implements IAicmsDiseaseService {
    @Autowired
    private ZerkProperties zerkProperties;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    /**
     * 男性疾病
     */
    private final List<String> maleDisease = new ArrayList<>(Arrays.asList("ZK_LHA", "ZK_LHB", "ZK_LHC", "ZK_LHD", "ZK_LHE", "ZK_LHF", "ZK_LHG", "ZK_LHI", "ZK_LHK", "ZK_YWG", "ZK_LXU"));
    /**
     * 女性疾病
     */
    private final List<String> femaleDisease = new ArrayList<>(Arrays.asList("ZK_GHA", "ZK_GHB", "ZK_GHC", "ZK_GHD", "ZK_GHE", "ZK_GHF", "ZK_THA", "ZK_LXM"));
    /**
     * 儿童疾病
     */
    private final List<String> childDisease = new ArrayList<>(Arrays.asList("ZK_WPB", "ZK_WPC", "ZK_WPD", "ZK_WPE", "ZK_WPF", "ZK_WPG", "ZK_WPI", "ZK_WPH"));
    /**
     * 老年疾病
     */
    private final List<String> oldDisease = new ArrayList<>(Collections.singletonList("ZK_WYB"));

    /**
     * 查询所有疾病
     *
     * @param depId
     * @param sex
     * @param age
     * @return
     */
    @Override
    public List<AicmsDisease> queryDiseases(String depId, String sex, String age) {
        QueryWrapper<AicmsDisease> q = new QueryWrapper<>();
        q.lambda().eq(AicmsDisease::getDepartmentId, depId);
        // 当科室为皮肤科（科室ID为8）时，特殊处理。数据库中皮肤科属于外科
        if (!"8".equals(depId)) {
//            criteria.andIsNull("pName");
            q.lambda().isNull(AicmsDisease::getPName);
        }
        List<AicmsDisease> list = list(q);
        log.info("根据科室ID查询疾病:{}", list);
        if (list == null || list.isEmpty()) {
            //本地没有数据, 请求接口数据
            try {
                String str = restTemplate.getForObject(zerkProperties.getJibingUrl() + depId, String.class);
                DiseaseVo vo = JSON.parseObject(str, DiseaseVo.class);
                log.info("根据科室获取疾病 参数keshiid=：" + depId);
                log.info("根据科室获取疾病结果：" + vo);
                if (vo != null && vo.getnErrorCode() == 0) {
                    return vo.getJibing();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return getAicmsDiseases(sex, age, list);
    }

    /**
     * 疾病id查询子疾病
     *
     * @param jibingId 疾病id
     * @return
     */
    @Override
    public List<AicmsDisease> querySubDiseases(String jibingId, String sex, String age) {
        QueryWrapper<AicmsDisease> q = new QueryWrapper<>();
        q.lambda().eq(AicmsDisease::getPId, jibingId);
        List<AicmsDisease> list = list(q);
        if (list == null || list.isEmpty()) {
            //本地没有数据, 请求接口数据
            try {
                String str = restTemplate.getForObject(zerkProperties.getSubJiBingUrl() + jibingId, String.class);
                DiseaseVo vo = JSON.parseObject(str, DiseaseVo.class);
                log.info("根据疾病获取子疾病 参数jibingId=：" + jibingId);
                log.info("根据疾病id获取疾病结果：" + vo);
                if (vo != null && vo.getnErrorCode() == 0) {
                    list = vo.getJibing();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return getAicmsDiseases(sex, age, list);
    }

    private List<AicmsDisease> getAicmsDiseases(String sex, String age, List<AicmsDisease> list) {
        int nl = -1;
        if (age != null) {
            if (age.contains(".")) {
                nl = Integer.parseInt(age.split("\\.")[0]);
            } else {
                nl = Integer.parseInt(age);
            }
        }
        if (nl > 17) {
            list = list.stream().filter(t -> !childDisease.contains(t.getSXuHao())).collect(Collectors.toList());
            if (nl < 60) {
                list = list.stream().filter(t -> !oldDisease.contains(t.getSXuHao())).collect(Collectors.toList());
            }
        }
        if (sex != null) {
            if ("男".equals(sex)) {
                list = list.stream().filter(t -> !femaleDisease.contains(t.getSXuHao())).collect(Collectors.toList());
                if (nl <= 17) {
                    list = list.stream().filter(t -> !maleDisease.contains(t.getSXuHao())).collect(Collectors.toList());
                }
            } else if ("女".equals(sex)) {
                list = list.stream().filter(t -> !maleDisease.contains(t.getSXuHao())).collect(Collectors.toList());
                if (nl <= 17) {
                    list = list.stream().filter(t -> !femaleDisease.contains(t.getSXuHao())).collect(Collectors.toList());
                }
            }
        }
        return list;
    }

    /**
     * 关键字搜索疾病
     *
     * @param keyword
     * @return
     */
    @Override
    public List<AicmsDisease> search(String keyword) {
        List<AicmsDisease> list = new ArrayList<>();
        if (StringUtils.isBlank(keyword)) {
            return list;
        }
        QueryWrapper<AicmsDisease> qw = new QueryWrapper<>();
        qw.lambda().like(AicmsDisease::getSName, keyword);
        list = list(qw);
        return list;
    }

    /**
     * 关键字搜索科室疾病症状
     *
     * @param keyword
     * @param timestamp
     * @param depId      科室id
     * @param nHaveChild
     * @return
     */
    @Override
    public List<SearchRes> searchAll(String keyword, String timestamp, String depId, Integer nHaveChild) {
        List<SearchRes> res = new ArrayList<>();
        if (StringUtils.isBlank(keyword)) {
            return res;
        }
        List<AicmsDisease> list = getBaseMapper().searchKeyword(keyword, depId, nHaveChild);
        for (AicmsDisease dis : list) {
            boolean has = false;
            for (SearchRes re : res) {
                if (dis.getDepartmentId().equals(re.getNID())) {
                    re.getList().add(dis);
                    has = true;
                    break;
                }
            }
            if (!has) {
                SearchRes sea = new SearchRes();
                List<AicmsDisease> di = new ArrayList<>();
                di.add(dis);
                sea.setNID(dis.getDepartmentId());
                sea.setSName(dis.getDepartmentName());
                sea.setList(di);
                res.add(sea);
            }
        }
        log.info("返回" + res);
        if (!StringUtils.isBlank(timestamp)) {
            String key = "page" + timestamp;
            Long num = redisTemplate.opsForValue().increment(key);
            if (num == 1) {
                redisTemplate.expire(key, 1, TimeUnit.HOURS);
            }
            int index = Math.toIntExact(num);
            if (index > res.size()) {
                redisTemplate.delete(key);
                return null;
            }
            return res.subList(index - 1, index);
        }
        return res;
    }

    /**
     * 查询科室和最终疾病
     *
     * @param req
     * @return
     */
    @Override
    public IPage<DepAndFindDiseaseRes> queryDepAndFindDisease(DepAndFindDiseaseReq req) {
        IPage<DepAndFindDiseaseRes> iPage = req.pagePojo();
        iPage = getBaseMapper().queryDepAndFindDisease(iPage, req);
        iPage.setRecords(handleList(iPage.getRecords(), req.getSex(), req.getAge()));
        return iPage;
    }

    public List<DepAndFindDiseaseRes> handleList(List<DepAndFindDiseaseRes> list, String sex, String age) {
        int nl = -1;
        if (age != null) {
            if (age.contains(".")) {
                nl = Integer.parseInt(age.split("\\.")[0]);
            } else {
                nl = Integer.parseInt(age);
            }
        }
        if (nl > 17) {
            list = list.stream().filter(t -> !childDisease.contains(t.getXuHao())).collect(Collectors.toList());
            list = list.stream().filter(t -> !t.getDepName().equals("儿科")).collect(Collectors.toList());
        }
        if (nl < 60) {
            list = list.stream().filter(t -> !oldDisease.contains(t.getXuHao())).collect(Collectors.toList());
            list = list.stream().filter(t -> !t.getDepName().equals("老年疾病")).collect(Collectors.toList());
        }
        if (sex != null) {
            if ("男".equals(sex)) {
                list = list.stream().filter(t -> !t.getDepName().equals("妇科")).collect(Collectors.toList());
                list = list.stream().filter(t -> !femaleDisease.contains(t.getXuHao())).collect(Collectors.toList());
                if (nl <= 17) {
                    list = list.stream().filter(t -> !maleDisease.contains(t.getXuHao())).collect(Collectors.toList());
                }
            } else if ("女".equals(sex)) {
                list = list.stream().filter(t -> !t.getDepName().equals("男科")).collect(Collectors.toList());
                list = list.stream().filter(t -> !maleDisease.contains(t.getXuHao())).collect(Collectors.toList());
                if (nl <= 17) {
                    list = list.stream().filter(t -> !femaleDisease.contains(t.getXuHao())).collect(Collectors.toList());
                }
            }
        }
        return list;
    }
}
